﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProtoGame.GameLib;
using ProtoGame.GameLib.Entities;
using Microsoft.Xna.Framework;
using ProtoGame.DescritoresContent;
using Microsoft.Xna.Framework.Audio;

namespace ProtoGame.Sprites
{
    class PGSpriteUrso : PGSpriteInimigo
    {
        const float velMovMin = (800 / (4f * 60)) / 1.5f;
        const float velMovMax = (800 / (4f * 60)) * 1.5f;
        const float velMovDelta = velMovMax - velMovMin;

        // Em segundos
        const double stateSpanMin = 2;
        const double stateSpanMax = 5;
        const double stateSpanDelta = stateSpanMax - stateSpanMin;

        static Random random = new Random();

        float velMov = velMovMin;
        TimeSpan stateSpan = TimeSpan.Zero;
        Vector2 direcao = Vector2.Zero;

        SoundEffect grito;

        public override Microsoft.Xna.Framework.Rectangle Bounds
        {
            get
            {
                // HACK: hardcoded :(
                Rectangle bounds = base.Bounds;
                bounds.Inflate(-6, -8);
                return bounds;
            }
        }

        public PGSpriteUrso(SoundEffect sfx, Tileset gfx)
            : base(PGIMGUrso.CriarAnimator(), gfx)
        {
            grito = sfx;
        }

        bool mudouDirecao = false;
        public override void Update(GameTime gameTime)
        {
            mudouDirecao = false;

            stateSpan -= gameTime.ElapsedGameTime;

            if (stateSpan <= TimeSpan.Zero)
                EscolheNovaAcao();

            Velocity = direcao * velMov;

            base.Update(gameTime);
        }

        private void EscolheNovaAcao()
        {
            int novoState = random.Next(5);

            direcao = Vector2.Zero;
            switch (novoState)
            {
                case 0: //Parado
                    direcao = Vector2.Zero;
                    break;

                case 1: //Pra cima
                    direcao.Y = -1;
                    AnimationState = PGIMGUrso.StateAndandoCima;
                    break;

                case 2: //Pra baixo
                    direcao.Y = 1;
                    AnimationState = PGIMGUrso.StateAndandoBaixo;
                    break;

                case 3: //Direita
                    direcao.X = 1;
                    AnimationState = PGIMGUrso.StateAndandoDireita;
                    break;

                case 4: // Esquerda
                    direcao.X = -1;
                    AnimationState = PGIMGUrso.StateAndandoEsquerda;
                    break;
            }

            if (direcao != Vector2.Zero)
            {
                //Define nova velocidade
                velMov = velMovMin + (velMovDelta * (float)random.NextDouble());

                direcao.Normalize();
            }

            AtualizaAnimationState();
            stateSpan = TimeSpan.FromSeconds(stateSpanMin + (stateSpanDelta * random.NextDouble()));
        }

        private void AtualizaAnimationState()
        {
            if (direcao != Vector2.Zero)
            {
                if (Math.Abs(direcao.X) >= Math.Abs(direcao.Y))
                    AnimationState = direcao.X > 0 ? PGIMGUrso.StateAndandoDireita : PGIMGUrso.StateAndandoEsquerda;
                else
                    AnimationState = direcao.Y < 0 ? PGIMGUrso.StateAndandoCima : PGIMGUrso.StateAndandoBaixo;
            }
            else
            {
                switch (AnimationState)
                {
                    case PGIMGUrso.StateAndandoBaixo:
                        AnimationState = PGIMGUrso.StateParadoBaixo;
                        break;

                    case PGIMGUrso.StateAndandoCima:
                        AnimationState = PGIMGUrso.StateParadoCima;
                        break;

                    case PGIMGUrso.StateAndandoDireita:
                        AnimationState = PGIMGUrso.StateParadoDireita;
                        break;

                    case PGIMGUrso.StateAndandoEsquerda:
                        AnimationState = PGIMGUrso.StateParadoEsquerda;
                        break;

                    default:
                        break;
                }
            }
        }

        protected override void MudaDirecao()
        {
            if (!mudouDirecao)
            {
                direcao = -direcao;
                mudouDirecao = true;

                AtualizaAnimationState();
            }
        }

        protected override void RecebeAtaque()
        {
            Visible = false;
            Alive = false;

            grito.Play();
        }
    }
}
